#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/completion.h>
#include <linux/kthread.h>
#include <linux/fs.h>
MODULE_LICENSE("GPL");
static char *who = "world";
static int times = 1;
module_param(times, int, S_IRUSR);
module_param(who, charp, 0644);
static int hello_data __initdata = 1;

struct task_struct *task[20];

int threadfn(void *data)
{
	u32 loop = 0xffff;
	u32 cpu_id = raw_smp_processor_id();
	u32 ncpu_id;
	u64 total = 100;
	u64 rand;
	printk(KERN_INFO "Running thread %u ", *(u32 *)data);
	while (loop--) {
		ncpu_id = raw_smp_processor_id();

		if (cpu_id != ncpu_id) {
			printk(KERN_ERR "not equal old cpuid %u, now %u",
			       cpu_id, ncpu_id);
			break;
		}

		//get_random_bytes(&rand, 4);
		total += jiffies;
	}

	printk(KERN_INFO "Stopped thread %u, total %llu", *(u32 *)data, total);
	return 0;
}

u32 threadids[20];
static int __init hello_init(void)
{
	int i;

	for (i = 0; i < 20; i++) {
		threadids[i] = i + 1;
		task[i] = kthread_run(threadfn, &threadids[i], "test cpu id");
	}

	for (i = 0; i < times; i++)
		printk(KERN_ALERT "(%d) hello, %s!\n", i, who);

#ifdef HELLO
	printk(KERN_ERR "Get MACRO HELLO");
#else
	printk(KERN_ERR "Without MACRO HELLO");
#endif
	printk(KERN_INFO "get data %d", hello_data);

	pr_info("info ---------- mesg\n");
	pr_debug("debug ---- msg\n");

	return 0;
}

void hello_api(void)
{
	printk(KERN_ALERT "Call, %s from module hello!\n", __func__);

	pr_info("get %d cpus\n", nr_cpu_ids);

	//complete((struct completion*));
}
EXPORT_SYMBOL_GPL(hello_api);

static void hello_exit(void)
{
	int i;
	printk(KERN_ALERT "Goodbye, %s!\n", who);
	for (i = 0; i < 20; i++) {
		kthread_stop(task[i]);
	}
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_DESCRIPTION("Module named hello.");
